package com.ly.emp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ly.common.core.bean.R;
import com.ly.common.core.bean.dto.CommonBatchUpdateDTO;
import com.ly.emp.bean.dto.HubTeamDTO;
import com.ly.emp.bean.dto.HubTeamResultBO;
import com.ly.emp.constant.EmpConstants;
import com.ly.emp.constant.EmpErrorConstants;
import com.ly.emp.entity.*;
import com.ly.emp.mapper.HubTeamResultMapper;
import com.ly.emp.service.*;
import com.ly.emp.util.TeamUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 考核结果-all-impl
 *
 * @author luoyun
 * @Date: 2025-05-20
 */
@Service
@RequiredArgsConstructor
public class HubTeamResultServiceImpl extends ServiceImpl<HubTeamResultMapper, HubTeamResult> implements IHubTeamResultService {

    private final IHubTeamCaseOrgService hubTeamCaseOrgService;
    private final IHubTeamMonitoringService hubTeamMonitoringService;
    private final IEmpCommonService teamCommonService;

    private final IHubTeamResultAddService hubTeamResultAddService;
    private final IHubTeamResultEvaluateService hubTeamResultEvaluateService;
    private final IHubTeamResultOrderService hubTeamResultOrderService;
    private final IHubTeamResultIndexService hubTeamResultIndexService;
    private final IHubTeamResultQuotaService hubTeamResultQuotaService;
    private final IHubTeamResultKeyTaskService hubTeamResultKeyTaskService;
    private final IHubBaseConfigService hubBaseConfigService;
    private final HubZsmsServiceIF hubZsmsServiceIF;

    /**
     * 汇总考核结果等级： 前20%为A，其他为B
     * TeamUtils.getHubTeamResultLevel(resultList);
     *
     * @param resultList
     * @return
     */
    public static void getHubTeamResultLevel(List<HubTeamResult> resultList) {
        // 分数过少时，都以B计算
        int scoreSize = resultList.size();
        if (scoreSize < 5) {
            resultList.stream().forEach(temp -> temp.setLevel("B"));
            return;
        }
        int scoreSize20 = scoreSize * 20 / 100;
        // System.out.println("分数总数个数："+scoreSize);
        // System.out.println("20%分数有效个数："+scoreSize20);
        // 排序
        resultList.stream().forEach(temp -> temp.setTempScore(new BigDecimal(temp.getFinalScore())));
        List<HubTeamResult> sortList = resultList.stream()
                .sorted(Comparator.comparing(HubTeamResult::getTempScore).reversed())
                .collect(Collectors.toList());
        for (int i = 0; i < sortList.size(); i++) {
            HubTeamResult hubTeamResult = sortList.get(i);
            if (i < scoreSize20) {
                hubTeamResult.setLevel("A");
            } else {
                hubTeamResult.setLevel("B");
            }
        }
    }

    @Override
    public R getId(String id) {
        HubTeamResult entity = this.getById(id);
        if (entity == null) {
            return R.fail("未找到对应数据");
        }
        return R.ok(entity);
    }

    @Override
    public R getList(HubTeamResult entity) {
        List<HubTeamResult> list = this.list(
                new LambdaQueryWrapper<HubTeamResult>()
                        .orderByAsc(HubTeamResult::getDisplayOrder)
        );
        return R.ok(list);
    }

    @Override
    public R getPage(HubTeamResult entity, Page<HubTeamResult> page) {
        String periodCode = entity.getPeriodCode();
        String orgCode = entity.getOrgCode();
        if (StrUtil.isBlank(periodCode)) {
            return R.fail(EmpErrorConstants.NO_PERIOD);
        }
        if (StrUtil.isBlank(orgCode)) {
            return R.fail(EmpErrorConstants.NO_TEAM);
        }
        List<String> isIntensificationList = teamCommonService.getIsIntensificationListByOrgCode(orgCode);
        IPage<HubTeamResult> pageList = this.page(page,
                new LambdaQueryWrapper<HubTeamResult>()
                        .in(HubTeamResult::getOrgCode, isIntensificationList)
                        .eq(HubTeamResult::getPeriodCode, periodCode)
                        .like(StrUtil.isNotBlank(entity.getPsnName()), HubTeamResult::getPsnName, entity.getPsnName())
                        .orderByAsc(HubTeamResult::getDisplayOrder)
        );
        List<HubTeamResult> records = pageList.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            // 封装初始分+折算分
            records.stream().forEach(n -> {
                for (int i = 1; i <= EmpConstants.resultScoreNum; i++) {
                    String finalScore = (String) ReflectUtil.getFieldValue(n, "elementScore" + i);
                    String originalScore = (String) ReflectUtil.getFieldValue(n, "elementScore" + i + "Original");
                    if (StrUtil.isNotBlank(finalScore)) {
                        ReflectUtil.setFieldValue(n, "elementScore" + i, finalScore + "（" + originalScore + "）");
                    }
                }
            });
        }
        return R.ok(pageList);
    }

    @Override
    public R add(HubTeamResult entity) {
        boolean flag = this.save(entity);
        return flag ? R.ok(true, "创建成功") : R.fail("创建失败");
    }

    @Override
    public R edit(HubTeamResult entity) {
        boolean flag = this.updateById(entity);
        return flag ? R.ok(true, "修改成功") : R.fail("修改失败");
    }

    @Override
    public R delete(String id) {
        boolean flag = this.removeById(id);
        return flag ? R.ok(true, "删除成功") : R.fail("删除失败");
    }

    @Override
    public R deleteBatch(String ids) {
        boolean flag = this.removeByIds(Arrays.asList(ids.split(",")));
        return flag ? R.ok(true, "批量删除成功") : R.fail("批量删除失败");
    }

    @Override
    public R updateBatch(CommonBatchUpdateDTO<HubTeamResult> dto) {
        // 批量新增
        List<HubTeamResult> datas = dto.getDatas();
        if (CollUtil.isNotEmpty(datas)) {
            // 清空封装的分数
            datas.stream().forEach(n -> {
                for (int i = 1; i <= EmpConstants.resultScoreNum; i++) {
                    ReflectUtil.setFieldValue(n, "elementScore" + i, null);
                }
            });
        }
        boolean flag = this.saveOrUpdateBatch(datas);
        return flag ? R.ok(true, "批量修改成功") : R.fail("批量修改失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R initSummary(HubTeamDTO dto) {
        String periodCode = dto.getPeriodCode();
        String orgCode = dto.getOrgCode();
        if (StrUtil.isBlank(periodCode)) {
            return R.fail(EmpErrorConstants.NO_PERIOD);
        }
        if (StrUtil.isBlank(orgCode)) {
            return R.fail(EmpErrorConstants.NO_TEAM);
        }
        // 查看班组的启动状态
        HubTeamMonitoring monitoring = hubTeamMonitoringService.getHubTeamMonitoringByParams(dto);
        if (monitoring == null) {
            // 班组汇总添加主状态
            EpmBaseSuitunitOrg baseSuitunitOrg = teamCommonService.getBaseSuitunitOrgByOrgCode(orgCode);
            HubTeamMonitoring hubTeamMonitoring = BeanUtil.copyProperties(baseSuitunitOrg, HubTeamMonitoring.class, new String[]{"id"});
            hubTeamMonitoring.setPeriodCode(periodCode);
            hubTeamMonitoring.setStatus(EmpConstants.RESULT_STATUS_SUMMARY);
            hubTeamMonitoringService.save(hubTeamMonitoring);
        } else {
            // 判断
            if (EmpConstants.RESULT_STATUS_PUBLISHED.equals(monitoring.getStatus())
                    || EmpConstants.RESULT_STATUS_PASS.equals(monitoring.getStatus())
                    || EmpConstants.RESULT_STATUS_SUBMIT.equals(monitoring.getStatus())
            ) {
                return R.fail(EmpErrorConstants.RESULT_INIT_ERR);
            }
            monitoring.setStatus(EmpConstants.RESULT_STATUS_SUMMARY);
            hubTeamMonitoringService.saveOrUpdate(monitoring);
        }
        // todo:ly2:需要处理黄花供电所以供电所来统计的情况
        // 1.找到班组需要考核的模块数据
        HubTeamCaseOrg hubTeamCaseOrg = new HubTeamCaseOrg();
        hubTeamCaseOrg.setOrgCode(dto.getOrgCode());
        hubTeamCaseOrg.setCaseStatus("true");
        R r = hubTeamCaseOrgService.getList(hubTeamCaseOrg);
        List<HubTeamCaseOrg> teamCaseOrgList = (List<HubTeamCaseOrg>) r.getResult();
        if (CollUtil.isEmpty(teamCaseOrgList)) {
            return R.fail(EmpErrorConstants.RESULT_NO_CASE);
        }
        // 获取k值
        HubBaseConfig baseConfig = hubBaseConfigService.getOne(
                new LambdaQueryWrapper<HubBaseConfig>()
                        .eq(HubBaseConfig::getOrgCode, orgCode)
        );
        if (baseConfig == null) {
            return R.fail(EmpErrorConstants.RESULT_NO_K);
        }
        BigDecimal k = baseConfig.getK();
        if (k == null) {
            return R.fail(EmpErrorConstants.RESULT_NO_K);
        }
        List<String> isIntensificationList = teamCommonService.getIsIntensificationListByOrgCode(orgCode);
        // 清空已有的数据
        this.remove(
                new LambdaQueryWrapper<HubTeamResult>()
                        .eq(HubTeamResult::getPeriodCode, periodCode)
                        .in(HubTeamResult::getOrgCode, isIntensificationList)
        );
        List<EpmBaseSuitunitOrg> orgs = teamCommonService.getBaseSuitunitOrgByOrgCodeList(isIntensificationList);
        Map<String, EpmBaseSuitunitOrg> orgsMap = orgs.stream().collect(Collectors.toMap(EpmBaseSuitunitOrg::getOrgCode, Function.identity(), (n1, n2) -> n1));
        // 全部人员列表
        List<EpmBaseRel> baseRelList = teamCommonService.getBaseRelListByOrgCode(null, orgCode);
        if (CollUtil.isEmpty(baseRelList)) {
            return R.fail(EmpErrorConstants.TEAM_STAFF_ERROR);
        }
        List<HubTeamResult> resultList = new ArrayList<>();
        // 设置初始信息
        baseRelList.stream().forEach(n -> {
            HubTeamResult result = BeanUtil.copyProperties(n, HubTeamResult.class, new String[]{"id"});
            // //设置父组织信息
            EpmBaseSuitunitOrg org = orgsMap.get(n.getOrgCode());
            if (org != null) {
                result.setParentOrgCode(org.getParentOrgCode());
                result.setParentOrgName(org.getParentOrgName());
            }
            result.setPeriodCode(periodCode);
            result.setStatus(EmpConstants.RESULT_STATUS_SUMMARY);
            resultList.add(result);
        });
        // 设置每一块的分数
        teamCaseOrgList.stream().forEach(n -> {
            wrapperTeamResultScoreByTeamCase(dto, resultList, n, k);
        });
        // 设置总分
        resultList.stream().forEach(n -> {
            BigDecimal sumBigDecimal = new BigDecimal("0");
            for (int i = 1; i <= EmpConstants.resultScoreNum; i++) {
                // 统计每一块的权重*分数
                BigDecimal tempScore = TeamUtils.getBigDecimal(String.valueOf(ReflectUtil.getFieldValue(n, "elementScore" + i)));
                BigDecimal tempWeight = TeamUtils.getBigDecimal(String.valueOf(ReflectUtil.getFieldValue(n, "elementScore" + i + "Weight")));
                BigDecimal tempSumScore = tempScore;
                if (new BigDecimal("0").compareTo(tempWeight) != 0) {
                    tempSumScore = tempScore.multiply(tempWeight).divide(new BigDecimal("100"));
                }
                sumBigDecimal = sumBigDecimal.add(tempSumScore);
            }
            // 去除尾部的0
            n.setFinalScore(sumBigDecimal.stripTrailingZeros().toPlainString());
        });
        this.getHubTeamResultLevel(resultList);
        boolean flag = this.saveOrUpdateBatch(resultList);
        return flag ? R.ok(true, "汇总成功") : R.fail("汇总失败");
    }

    @Override
    public R publishSummary(HubTeamDTO dto) {
        String orgCode = dto.getOrgCode();
        String periodCode = dto.getPeriodCode();
        String type = dto.getType();
        String status = null;
        if ("submit".equals(type)) {
            status = EmpConstants.RESULT_STATUS_SUBMIT;
        } else if ("release".equals(type)) {
            status = EmpConstants.RESULT_STATUS_PUBLISHED;
        } else if ("reject".equals(type)) {
            status = EmpConstants.RESULT_STATUS_REJECT;
        } else if ("pass".equals(type)) {
            status = EmpConstants.RESULT_STATUS_PASS;
        }
        if (StrUtil.isBlank(status)) {
            return R.fail(EmpErrorConstants.REQ_PARAMS_ERROR);
        }
        // 查看班组的启动状态
        HubTeamMonitoring monitoring = hubTeamMonitoringService.getHubTeamMonitoringByParams(dto);
        if (monitoring == null) {
            // 判断是否允许操作
            if (EmpConstants.RESULT_STATUS_REJECT.equals(status)
                    || EmpConstants.RESULT_STATUS_SUBMIT.equals(status)
                    || EmpConstants.RESULT_STATUS_PASS.equals(status)
                    || EmpConstants.RESULT_STATUS_PUBLISHED.equals(status)) {
                return R.fail(EmpErrorConstants.RESULT_NO_INIT);
            }
            // 班组汇总添加主状态
            EpmBaseSuitunitOrg baseSuitunitOrg = teamCommonService.getBaseSuitunitOrgByOrgCode(orgCode);
            HubTeamMonitoring hubTeamMonitoring = BeanUtil.copyProperties(baseSuitunitOrg, HubTeamMonitoring.class, new String[]{"id"});
            hubTeamMonitoring.setPeriodCode(periodCode);
            hubTeamMonitoring.setOrgCode(orgCode);
            hubTeamMonitoring.setStatus(status);
            hubTeamMonitoringService.saveOrUpdate(hubTeamMonitoring);
        } else {
            String currentStatus = monitoring.getStatus();
            if (EmpConstants.RESULT_STATUS_REJECT.equals(status)) {
                // 退回已经发布的，或已经审核通过的
                if (!(EmpConstants.RESULT_STATUS_PUBLISHED.equals(currentStatus) || EmpConstants.RESULT_STATUS_PASS.equals(currentStatus))) {
                    return R.fail(EmpErrorConstants.RESULT_NO_REJECT);
                }
            } else if (EmpConstants.RESULT_STATUS_PASS.equals(status)) {
                // 审核通过已提交的和 审核退回的
                if (!(EmpConstants.RESULT_STATUS_REJECT.equals(currentStatus) || EmpConstants.RESULT_STATUS_SUBMIT.equals(currentStatus))) {
                    return R.fail(EmpErrorConstants.RESULT_NO_PASS);
                }
            } else if (EmpConstants.RESULT_STATUS_SUBMIT.equals(status)) {
                // 提交已汇总的和 审核退回的
                if (!(EmpConstants.RESULT_STATUS_SUMMARY.equals(currentStatus) || EmpConstants.RESULT_STATUS_INIT.equals(currentStatus) || EmpConstants.RESULT_STATUS_REJECT.equals(currentStatus))) {
                    return R.fail(EmpErrorConstants.RESULT_NO_SUBMIT1);
                }
            } else {
                // 只能审核通过或审核退回 已提交的数据
                if ((EmpConstants.RESULT_STATUS_REJECT.equals(status) || EmpConstants.RESULT_STATUS_PASS.equals(status))
                        && !EmpConstants.RESULT_STATUS_SUBMIT.equals(currentStatus)) {
                    return R.fail(EmpErrorConstants.RESULT_NO_SUBMIT);
                }
                // 发布前判断
                if (EmpConstants.RESULT_STATUS_PUBLISHED.equals(status)) {
                    // 验证重复发布问题
                    if (EmpConstants.RESULT_STATUS_PUBLISHED.equals(currentStatus)) {
                        return R.fail(EmpErrorConstants.RESULT_HAS_PUBLISHED);
                    }
                    // 只能发布已审核通过的数据
                    if (!EmpConstants.RESULT_STATUS_PASS.equals(currentStatus)) {
                        return R.fail(EmpErrorConstants.RESULT_NO_PUBLISHED);
                    }
                }
            }
            monitoring.setOrgCode(orgCode);
            monitoring.setStatus(status);
            hubTeamMonitoringService.saveOrUpdate(monitoring);
        }
        List<String> isIntensificationListByOrgCode = teamCommonService.getIsIntensificationListByOrgCode(orgCode);
        List<HubTeamResult> list = this.list(
                new LambdaQueryWrapper<HubTeamResult>()
                        .eq(HubTeamResult::getPeriodCode, periodCode)
                        .in(HubTeamResult::getOrgCode, isIntensificationListByOrgCode)
        );
        if (CollUtil.isNotEmpty(list)) {
            String finalStatus = status;
            list.stream().forEach(n -> n.setStatus(finalStatus));
        }
        boolean b = this.saveOrUpdateBatch(list);
        return R.ok(true, "操作成功");
    }

    /**
     * 根据积分折算模式求取对应的分数，积分模式：M00001: 不折算   M00002：插值法  M00003：平均分标杆   M00004：最高分标杆法
     *
     * @param dto
     * @param resultList
     * @param teamCaseOrg
     * @return
     */
    private void wrapperTeamResultScoreByTeamCase(HubTeamDTO dto, List<HubTeamResult> resultList, HubTeamCaseOrg teamCaseOrg, BigDecimal k) {
        // 找到对应方案编码，查询对应数据库
        String caseCode = teamCaseOrg.getCaseCode();
        List<HubTeamResultBO> bos = new ArrayList<>();
        if ("jichu".equals(caseCode)) {
            // 基础定额：一人一条
            HubTeamResultQuota entity = BeanUtil.toBean(dto, HubTeamResultQuota.class);
            R r = hubTeamResultQuotaService.getList(entity);
            List<HubTeamResultQuota> list = (List<HubTeamResultQuota>) r.getResult();
            if (CollUtil.isNotEmpty(list)) {
                list.stream().forEach(t -> bos.add(BeanUtil.toBean(t, HubTeamResultBO.class)));
            }
        } else if ("workpoint".equals(caseCode)) {
            // 重点工作：一人多条
            HubTeamResultKeyTask entity = BeanUtil.toBean(dto, HubTeamResultKeyTask.class);
            R r = hubTeamResultKeyTaskService.getList(entity);
            List<HubTeamResultKeyTask> list = (List<HubTeamResultKeyTask>) r.getResult();
            if (CollUtil.isNotEmpty(list)) {
                list.stream().forEach(t -> bos.add(BeanUtil.toBean(t, HubTeamResultBO.class)));
            }
        } else if ("index".equals(caseCode)) {
            // 指标考核：一人多条
            HubTeamResultIndex entity = BeanUtil.toBean(dto, HubTeamResultIndex.class);
            R r = hubTeamResultIndexService.getList(entity);
            List<HubTeamResultIndex> list = (List<HubTeamResultIndex>) r.getResult();
            if (CollUtil.isNotEmpty(list)) {
                list.stream().forEach(t -> bos.add(BeanUtil.toBean(t, HubTeamResultBO.class)));
            }
        } else if ("workorder".equals(caseCode)) {
            // 工单公分：一人多条
            TeamResultOrderDetail entity = BeanUtil.toBean(dto, TeamResultOrderDetail.class);
            R r = hubTeamResultOrderService.getList(entity);
            List<TeamResultOrderDetail> list = (List<TeamResultOrderDetail>) r.getResult();
            if (CollUtil.isNotEmpty(list)) {
                list.stream().forEach(t -> {
                    HubTeamResultBO hubTeamResultBO = BeanUtil.toBean(t, HubTeamResultBO.class);
                    hubTeamResultBO.setFinalScore(TeamUtils.getBigDecimal(t.getSumPoints()));
                    bos.add(hubTeamResultBO);
                });
            }
        } else if ("access".equals(caseCode)) {
            // 综合评价：一人一条
            HubTeamResultEvaluate entity = BeanUtil.toBean(dto, HubTeamResultEvaluate.class);
            R r = hubTeamResultEvaluateService.getList(entity);
            List<HubTeamResultEvaluate> list = (List<HubTeamResultEvaluate>) r.getResult();
            if (CollUtil.isNotEmpty(list)) {
                list.stream().forEach(t -> bos.add(BeanUtil.toBean(t, HubTeamResultBO.class)));
            }
        } else if ("addsub".equals(caseCode)) {
            // 加减分：一人多条
            HubTeamResultAdd entity = BeanUtil.toBean(dto, HubTeamResultAdd.class);
            R r = hubTeamResultAddService.getList(entity);
            List<HubTeamResultAdd> list = (List<HubTeamResultAdd>) r.getResult();
            if (CollUtil.isNotEmpty(list)) {
                list.stream().forEach(t -> bos.add(BeanUtil.toBean(t, HubTeamResultBO.class)));
            }
        }
        hubZsmsServiceIF.getTeamResultScore(bos, resultList, teamCaseOrg, k);
    }
}
